package org.altervista.cp.microkernel;

import java.io.IOException;
import java.util.HashMap;
import java.util.logging.FileHandler;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.StreamHandler;

import org.altervista.cp.microkernel.log.LogContext;

public class LogContextHandler extends StreamHandler {

	public LogContextHandler() throws SecurityException, IOException {
		super();
		configure();
	}

	public void close() {
		getFileHandler().close();
	}

	public void flush() {
		getFileHandler().flush();
	}

	public void publish(LogRecord record) {
		getFileHandler().publish(record);
	}

	private void configure() {
		LogManager manager = LogManager.getLogManager();

		String cname = getClass().getName();

		pattern = getProperty(manager, cname + ".pattern", "%h/java%u.log");
		limit = Integer.parseInt(getProperty(manager, cname + ".limit", "0"));
		count = Integer.parseInt(getProperty(manager, cname + ".count", "1"));
		append = Boolean.parseBoolean(getProperty(manager, cname + ".append",
				"true"));
	}

	private FileHandler getFileHandler() {
		synchronized (_handlers) {
			String logContext = LogContext.currentLogContext().toString();
			FileHandler fh = _handlers.get(logContext);
			if (fh == null) {
				fh = newFileHandler(logContext);
				_handlers.put(logContext, fh);
			}
			fh.setFilter(getFilter());
			return fh;
		}
	}

	private String getProperty(LogManager manager, String key,
			String defaultValue) {
		String value = manager.getProperty(key);
		return value == null ? defaultValue : value;
	}

	private FileHandler newFileHandler(String logContext) {
		String contextPattern = _LOG_DIRECTORY_PATH + "/"
				+ pattern.replace("${logcontext}", logContext);

		FileHandler fh = null;
		try {
			fh = new FileHandler(contextPattern, limit, count, append);
			fh.setEncoding(getEncoding());
		} catch (IOException e) {
			throw new IllegalStateException(e);
		}
		fh.setErrorManager(getErrorManager());
		fh.setFormatter(getFormatter());
		fh.setLevel(getLevel());
		return fh;
	}

	private boolean append;
	private int count;
	private int limit;
	private String pattern;

	private static final HashMap<String, FileHandler> _handlers = new HashMap<String, FileHandler>();

	static String _LOG_DIRECTORY_PATH;

}
